package com.lqd.mall.jpa.repository.impl;

import com.lqd.mall.jpa.constant.SqlUniversalConstants;
import com.lqd.mall.jpa.repository.BaseRepository;
import com.lqd.mall.jpa.utils.DynamicSqlUtil;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author 零起点
 * @create 2022-03-05 10:21
 */
public class BaseRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
        implements BaseRepository<T, ID> {

    private final EntityManager entityManager;


    @Override
    public Optional<Integer> delectEntity(T entity) {

        int update;

        StringBuilder builder = new StringBuilder();
        builder.append(SqlUniversalConstants.DELETE).append(SqlUniversalConstants.FROM);
        builder.append(DynamicSqlUtil.getTabaleName(entity)).append(" ");
        builder.append(SqlUniversalConstants.WHERE).append(" 1 = 1");
        Map<String, Object> params = new HashMap<>();
        StringBuilder where = DynamicSqlUtil.getWhere(entity, params);
        if (where.length() > 0) {
            builder.append(SqlUniversalConstants.AND);
            builder.append(where.toString());
        }
        //nativeQuery
        Query query = entityManager.createNativeQuery(builder.toString(), entity.getClass());
        params.forEach(query::setParameter);
        update = query.executeUpdate();
        return Optional.of(update);
    }

    @Override
    public Optional<Integer> updateEntity(T entity, String[] attribute) {
        StringBuilder sql = new StringBuilder();
        // 修改语句的固定式
        sql.append(SqlUniversalConstants.UPDATE)
                .append(DynamicSqlUtil.getTabaleName(entity))
                .append(SqlUniversalConstants.SET);
        //获取到  字段信息
        Map<String, Object> forFilds = DynamicSqlUtil.forFieldsValues(entity);
        Map<String, Object> map = new HashMap<>();
        List<String> conditions = Arrays.asList(attribute);
        forFilds.forEach((key, vault) -> {
            if (conditions.contains(key)) {
                map.put(key, vault);
            }
        });
        //删除条件部分
        conditions.forEach(forFilds::remove);
        if (forFilds.size() == 0) {
            return Optional.of(0);
        }
        Map<String, Object> params = new HashMap<>();
        // 封装
        forFilds.forEach((field,value)->{
            sql.append(field).append(SqlUniversalConstants.IS_EQUAL_TO_THE)
                    .append(SqlUniversalConstants.COLON).append(field)
                    .append(SqlUniversalConstants.COMMA);
            params.put(field,value);
        });
         if(sql.toString().endsWith(SqlUniversalConstants.COMMA)){
             sql.delete(sql.toString().length()-SqlUniversalConstants.COMMA.length(),sql.toString().length());
         }
        // 封装条件
        StringBuilder where = DynamicSqlUtil.generateQueryConditions(map, params);
         if(where.length() ==  0){
             return Optional.of(0);
         }
         sql.append(SqlUniversalConstants.WHERE);
        sql.append(where);
        Query query = entityManager.createNativeQuery(sql.toString(), entity.getClass());
        params.forEach(query::setParameter);
        return Optional.of(query.executeUpdate());
    }

    //父类没有不带参数的构造方法，这里手动构造父类
    public BaseRepositoryImpl(Class<T> domainClass, EntityManager entityManager) {
        super(domainClass, entityManager);
        this.entityManager = entityManager;
    }

}
